#include "PhysicsLayer.h"
#include <SECore/CoreApplication.h>
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
#include <SEPhysics/Entity/RigidBodyPayload.h>


namespace SEngine
{

    PhysicsLayer::PhysicsLayer(CoreApplication &app)
        : Layer(app)
    {
        m_btConfig = new btDefaultCollisionConfiguration();
        m_btDispatcher = new btCollisionDispatcher(m_btConfig);    
        m_btSolver = new btSequentialImpulseConstraintSolver();
        m_btBroadphase = new btDbvtBroadphase();
        m_btWorld = new btDiscreteDynamicsWorld(m_btDispatcher, m_btBroadphase, m_btSolver, m_btConfig);
        m_btWorld->setGravity(btVector3{0.0f, -98.0f, 0.0f});
    }

    PhysicsLayer::~PhysicsLayer()
    {
        delete m_btWorld;
        delete m_btBroadphase;
        delete m_btSolver;
        delete m_btDispatcher;
        delete m_btConfig;
    }

    void PhysicsLayer::Attach()
    {
    }

    void PhysicsLayer::Update(int delta)
    {
        if (m_btWorld->stepSimulation(delta * 0.001f, 10)) {
            for (auto [_, body] : m_bodies) {
                body->OnUpdateTransform();
            }
        } 
    }
    
    void PhysicsLayer::SlotAddComponent(IComponent & comp)
    {
        if (auto body = dynamic_cast<RigidBodyPayload*>(&comp); body) {
            m_btWorld->addRigidBody(body->GetBody());
            // body->SignalAddBody.AddSlot([this](btRigidBody* body) {
            //     m_btWorld->addRigidBody(body);
            //     return SlotState::Keep;
            // });
            // body->SignalRemoveBody.AddSlot([this](btRigidBody* body) {
            //     m_btWorld->removeRigidBody(body);
            //     return SlotState::Keep;
            // });
            m_bodies.emplace(&comp, body);
        }
    }
    
    void PhysicsLayer::SlotRemoveComponent(IComponent & comp)
    {
        if (auto body = dynamic_cast<RigidBodyPayload*>(&comp); body) {
            m_btWorld->removeRigidBody(body->GetBody());
            m_bodies.erase(&comp);
        }
    }
} // namespace SEngine
